#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
struct GrayImage {  //定义结构体存储灰度图像信息，包括矩阵对象，图像的宽度与高度
    Mat image;
    int width;
    int heiget;
};
void printImageWH(Mat& image);     //打印出图像的宽度与高度
Mat process(Mat& input);           //图像处理函数，返回直方图均衡化之后的图像
void printImagePixel(Mat& image);  //打印图像像素信息
int grey[256] = {0};               //统计各个灰度级的像素点出现的频数
double grey_prob[256] = {0};       //定义数组存储各个灰度级出现的概率
double grey_sumprob[256] = {0};    //求解概率密度
int grey_result[256] = {0};        //记录均很化之后的结果
int grey_sum = 0;                  //定义数组存储总的像素数
int main() {
    Mat src = imread("/home/dao/桌面/demo/src/first.png");
    Mat dst;
    resize(src, dst, Size(), 0.2, 0.2);
    Mat m1;
    cvtColor(dst, m1, COLOR_BGR2GRAY);
    Mat m2 = process(m1);
    printImageWH(m1);
    printImageWH(m2);
    imshow("begin", m1);
    imshow("last", m2);
    std::cout << m1 << std::endl;
    std::cout << m2 << std::endl;
    waitKey(0);
    return 0;
}

Mat process(Mat& image) {
    Mat image_copy = image.clone();
    grey_sum = image.cols * image.rows;
    //遍历图像每一个像素点，统计各个灰度级像素点出现的次数
    for (int i = 0; i < image_copy.rows; i++) {
        uchar* p = image_copy.ptr<uchar>(i);
        for (int j = 0; j < image_copy.cols; j++) {
            int vaule = p[j];
            grey[vaule]++;
        }
    }
    //计算概率，根据频次计算
    for (int i = 0; i < 256; i++) {
        grey_prob[i] = double(grey[i]) / grey_sum;
    }
    //得到概率密度分布
    grey_sumprob[0] = grey_prob[0];
    for (int i = 1; i < 255; i++) {
        grey_sumprob[i] = grey_sumprob[i - 1] + grey_prob[i];
    }
    //根据结论计算得到最后结果
    for (int i = 0; i < 256; i++) {
        grey_result[i] = (uchar)(255 * grey_sumprob[i] + 0.5);
    }
    //更新图像的像素值
    for (int i = 0; i < image_copy.rows; i++) {
        uchar* p = image_copy.ptr<uchar>(i);
        for (int j = 0; j < image_copy.cols; j++) {
            p[j] = grey_result[p[j]];
        }
    }
    return image_copy;
}
void printImagePixel(Mat& image) {
    for (int i = 0; i < image.rows; i++) {
        uchar* p = image.ptr<uchar>(i);
        for (int j = 0; j < image.cols; j++) {
            std::cout << p[j] << std::endl;
        }
    }
}
void printImageWH(Mat& image) {
    std::cout << "图像宽度为" << image.cols << std::endl;
    std::cout << "图像高度为" << image.rows << std::endl;
}
